#ifndef			_XANADU_CORE_NAMESPACE_STRING_H_
#define			_XANADU_CORE_NAMESPACE_STRING_H_

#include <XanaduCore/XHeader.h>
#include <XanaduCore/XAllocator.h>
#include <XanaduCore/XByteArray.h>


// String type definition
typedef			char							XChar;
typedef			std::string						AString;		// ASCII
typedef			std::wstring						WString;		// UNICODE
typedef			std::string						UString;		// UTF-8
typedef			std::string						LString;		// Latin1(ISO-8859-1)

// Defines the encoding used by native strings based on the platform type
#if defined(_XANADU_SYSTEM_WINDOWS)
typedef			AString							NString;
#else
typedef			UString							NString;
#endif


/// <summary>
///  A string processing class of UTF-8.
/// </summary>
class XANADU_CORE_EXPORT XString final
{
public:
	using				_Elem = char;
	using				size_type = std::size_t;

public:
	static const size_type		npos = static_cast<size_type>(-1);

private:
	_Elem*				_string_data = nullptr;
	size_type			_string_length = 0U;
	size_type			_string_capacity = 0U;

public:
	// constructor
	XString() noexcept;

	// constructor
	XString(size_type _Count, _Elem _Char) noexcept;

	// constructor
	XString(const _Elem* _String) noexcept;

	// constructor
	XString(const _Elem* _String, size_type _Length) noexcept;

	// constructor
	XString(const std::string& _String) noexcept;

	// constructor
	XString(const std::string& _String, size_type _Count) noexcept;

	// constructor
	XString(const XByteArray& _Bytes) noexcept;

	// constructor
	XString(const XByteArray& _Bytes, size_type _Count) noexcept;

	// constructor
	XString(const XString& _String) noexcept;

	// constructor
	XString(const XString& _String, size_type _Count) noexcept;

	// constructor
	XString(XString&& _String) noexcept;

	// destructor
	virtual ~XString() noexcept;

private:
	// memory: Computing demand space
	size_type _memory_calculation_capacity(size_type _Length) const noexcept;

	// memory: malloc
	bool _memory_malloc(size_type _Length) noexcept;

	// memory: resize
	bool _memory_resize(size_type _Length) noexcept;

	// memory: surplus
	size_type _memory_surplus() const noexcept;

	// memory: free
	void _memory_free() noexcept;

private:
	// fix: pos
	size_type _fix_pos(size_type _Pos) const noexcept;

	// fix: length
	size_type _fix_length(const _Elem* _String, size_type _Length) const noexcept;

private:
	// private: contains
	bool _contains(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) const noexcept;

	// private: compare
	int _compare(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) const noexcept;

	// private: find
	size_type _find(const _Elem* _String, size_type _Length, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// private: rfind
	size_type _rfind(const _Elem* _String, size_type _Length, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// private: prepend
	void _prepend(const _Elem* _String, size_type _Length) noexcept;

	// private: insert
	void _insert(size_type _Pos, const _Elem* _String, size_type _Length) noexcept;

	// private: append
	void _append(const _Elem* _String, size_type _Length) noexcept;

	// private: remove
	void _remove(size_type _Pos, size_type _Length) noexcept;

	// private: remove
	void _remove(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) noexcept;

	// private: replace
	void _replace(size_type _Pos, size_type _Length, const _Elem* _After, size_type _LengthA) noexcept;

	// private: replace
	void _replace(const _Elem* _Before, size_type _LengthB, const _Elem* _After, size_type _LengthA, Xanadu::CaseSensitivity _XCS) noexcept;

	// private: middle
	XString _middle(const _Elem* _Left, size_type _LengthL, const _Elem* _Right, size_type _LengthR, Xanadu::CaseSensitivity _XCS) const noexcept;

	// private: startsWith
	bool _startsWith(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) const noexcept;

	// private: endsWith
	bool _endsWith(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// [opt] operators overload =
	XString& operator = (const _Elem* _String) noexcept;

	// [opt] operators overload =
	XString& operator = (const std::string& _String) noexcept;

	// [opt] operators overload =
	XString& operator = (const XByteArray& _Bytes) noexcept;

	// [opt] operators overload =
	XString& operator = (const XString& _String) noexcept;

	// [opt] operators overload =
	XString& operator = (XString&& _String) noexcept;

public:
	// [opt] operators overload []
	_Elem& operator [] (size_type _Index);

	// [opt] operators overload []
	_Elem operator [] (size_type _Index) const;

public:
	// [opt] operators overload +=
	XString& operator += (_Elem _Char) noexcept;

	// [opt] operators overload +=
	XString& operator += (const _Elem* _String) noexcept;

	// [opt] operators overload +=
	XString& operator += (const std::string& _String) noexcept;

	// [opt] operators overload +=
	XString& operator += (const XString& _String) noexcept;

public:
	// [opt] operators overload +
	XString operator + (_Elem _Char) const noexcept;

	// [opt] operators overload +
	XString operator + (const _Elem* _String) const noexcept;

	// [opt] operators overload +
	XString operator + (const std::string& _String) const noexcept;

	// [opt] operators overload +
	XString operator + (const XString& _String) const noexcept;

public:
	// [opt] operators overload ==
	bool operator == (_Elem _Char)const noexcept;

	// [opt] operators overload ==
	bool operator == (const _Elem* _String)const noexcept;

	// [opt] operators overload ==
	bool operator == (const XString& _String)const noexcept;

	// [opt] operators overload !=
	bool operator != (_Elem _Char)const noexcept;

	// [opt] operators overload !=
	bool operator != (const _Elem* _String)const noexcept;

	// [opt] operators overload !=
	bool operator != (const XString& _String)const noexcept;

	// [opt] operators overload <
	bool operator < (_Elem _Char)const noexcept;

	// [opt] operators overload <
	bool operator < (const _Elem* _String)const noexcept;

	// [opt] operators overload <
	bool operator < (const XString& _String)const noexcept;

	// [opt] operators overload >
	bool operator > (_Elem _Char)const noexcept;

	// [opt] operators overload >
	bool operator > (const _Elem* _String) const noexcept;

	// [opt] operators overload >
	bool operator > (const XString& _String) const noexcept;

	// [opt] operators overload <=
	bool operator <= (_Elem _Char)const noexcept;

	// [opt] operators overload <=
	bool operator <= (const _Elem* _String) const noexcept;

	// [opt] operators overload <=
	bool operator <= (const XString& _String) const noexcept;

	// [opt] operators overload >=
	bool operator >= (_Elem _Char)const noexcept;

	// [opt] operators overload >=
	bool operator >= (const _Elem* _String) const noexcept;

	// [opt] operators overload >=
	bool operator >= (const XString& _String) const noexcept;

public:
	// [get] Is there a string
	bool exist() const noexcept;

	// [get] Is there a string
	bool empty() const noexcept;

	// [get] a C compatible string ending with '\0'
	_Elem* data() noexcept;

	// [get] a C compatible string ending with '\0'
	const _Elem* data() const noexcept;

	// [get] length of string
	size_type size() const noexcept;

	// [get] length of string
	size_type length() const noexcept;

	// [get] capacity of string
	size_type capacity() const noexcept;

public:
	// Empty all spaces with 0
	void clear() noexcept;

	// Exchange string
	void swap(XString& _String) noexcept;

	// Gets the maximum length allowed
	size_type max_size() const noexcept;

	// Resizing
	void resize(size_type _Length) noexcept;

	// Resizing
	void resize(size_type _Length, _Elem _Char) noexcept;

	// Truncates the subscript POS of the byte array. If POS goes beyond the end of the array, nothing happens.
	void truncate(size_type _Index) noexcept;

	// Returns a string that has whitespace removed from the start and the end, and that has each sequence of internal whitespace replaced with a single space.
	XString simplified() const noexcept;

public:
	// Extracting substrings from strings
	XString substr(size_type _Pos) const noexcept;

	// Extracting substrings from strings
	XString substr(size_type _Pos, size_type _Length) const noexcept;

	// Gets the substring to the left of the source string
	XString left(size_type _Pos) const noexcept;

	// Gets the substring to the right of the source string
	XString right(size_type _Pos) const noexcept;

public:
	// [mid] Gets the substring in the middle of the source string
	XString mid(size_type _Pos) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(size_type _Pos, size_type _Size) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const _Elem* _Left, const _Elem* _Right) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const _Elem* _Left, const _Elem* _Right, Xanadu::CaseSensitivity _XCS) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const _Elem* _Left, const XString& _Right) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const _Elem* _Left, const XString& _Right, Xanadu::CaseSensitivity _XCS) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const XString& _Left, const _Elem* _Right) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const XString& _Left, const _Elem* _Right, Xanadu::CaseSensitivity _XCS) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const XString& _Left, const XString& _Right) const noexcept;

	// [mid] Gets the substring in the middle of the source string
	XString mid(const XString& _Left, const XString& _Right, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// Detects whether the string starts with the specified prefix
	bool startsWith(_Elem _Char) const noexcept;

	// Detects whether the string starts with the specified prefix
	bool startsWith(_Elem _Char, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Detects whether the string starts with the specified prefix
	bool startsWith(const _Elem* _Memory) const noexcept;

	// Detects whether the string starts with the specified prefix
	bool startsWith(const _Elem* _Memory, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Detects whether the string starts with the specified prefix
	bool startsWith(const _Elem* _Memory, size_type _Length) const noexcept;

	// Detects whether the string starts with the specified prefix
	bool startsWith(const _Elem* _Memory, size_type _Length, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Detects whether the string starts with the specified prefix
	bool startsWith(const XString& _String) const noexcept;

	// Detects whether the string starts with the specified prefix
	bool startsWith(const XString& _String, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// Detects whether the string ends with the specified suffix
	bool endsWith(_Elem _Char) const noexcept;

	// Detects whether the string ends with the specified suffix
	bool endsWith(_Elem _Char, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Detects whether the string ends with the specified suffix
	bool endsWith(const _Elem* _Memory) const noexcept;

	// Detects whether the string ends with the specified suffix
	bool endsWith(const _Elem* _Memory, Xanadu::CaseSensitivity) const noexcept;

	// Detects whether the string ends with the specified suffix
	bool endsWith(const _Elem* _Memory, size_type _Length) const noexcept;

	// Detects whether the string ends with the specified suffix
	bool endsWith(const _Elem* _Memory, size_type _Length, Xanadu::CaseSensitivity) const noexcept;

	// Detects whether the string ends with the specified suffix
	bool endsWith(const XString& _String) const noexcept;

	// Detects whether the string ends with the specified suffix
	bool endsWith(const XString& _String, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// Find in positive order from the specified location
	size_type find(_Elem _Char) const noexcept;

	// Find in positive order from the specified location
	size_type find(_Elem _Char, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Find in positive order from the specified location
	size_type find(_Elem _Char, size_type _Pos) const noexcept;

	// Find in positive order from the specified location
	size_type find(_Elem _Char, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Find in positive order from the specified location
	size_type find(const _Elem* _String) const noexcept;

	// Find in positive order from the specified location
	size_type find(const _Elem* _String, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Find in positive order from the specified location
	size_type find(const _Elem* _String, size_type _Pos) const noexcept;

	// Find in positive order from the specified location
	size_type find(const _Elem* _String, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Find in positive order from the specified location
	size_type find(const _Elem* _String, size_type _Length, size_type _Pos) const noexcept;

	// Find in positive order from the specified location
	size_type find(const _Elem* _String, size_type _Length, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Find in positive order from the specified location
	size_type find(const XString& _String) const noexcept;

	// Find in positive order from the specified location
	size_type find(const XString& _String, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Find in positive order from the specified location
	size_type find(const XString& _String, size_type _Pos) const noexcept;

	// Find in positive order from the specified location
	size_type find(const XString& _String, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// Search in reverse order from the specified location
	size_type rfind(_Elem _Char) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(_Elem _Char, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(_Elem _Char, size_type _Pos) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(_Elem _Char, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const _Elem* _String) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const _Elem* _String, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const _Elem* _String, size_type _Pos) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const _Elem* _String, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const _Elem* _String, size_type _Length, size_type _Pos) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const _Elem* _String, size_type _Length, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const XString& _String) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const XString& _String, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const XString& _String, size_type _Pos) const noexcept;

	// Search in reverse order from the specified location
	size_type rfind(const XString& _String, size_type _Pos, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// Check whether the specified content is included
	bool contains(_Elem _Char) const noexcept;

	// Check whether the specified content is included
	bool contains(_Elem _Char, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Check whether the specified content is included
	bool contains(const _Elem* _String) const noexcept;

	// Check whether the specified content is included
	bool contains(const _Elem* _String, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Check whether the specified content is included
	bool contains(const _Elem* _String, size_type _Length) const noexcept;

	// Check whether the specified content is included
	bool contains(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Check whether the specified content is included
	bool contains(const XString& _String) const noexcept;

	// Check whether the specified content is included
	bool contains(const XString& _String, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// Check that they are the same
	int compare(_Elem _Char) const noexcept;

	// Check that they are the same
	int compare(_Elem _Char, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Check that they are the same
	int compare(const _Elem* _String) const noexcept;

	// Check that they are the same
	int compare(const _Elem* _String, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Check that they are the same
	int compare(const _Elem* _String, size_type _Length) const noexcept;

	// Check that they are the same
	int compare(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) const noexcept;

	// Check that they are the same
	int compare(const XString& _String) const noexcept;

	// Check that they are the same
	int compare(const XString& _String, Xanadu::CaseSensitivity _XCS) const noexcept;

public:
	// Add at the begin
	XString& prepend(_Elem _Char) noexcept;

	// Add at the begin
	XString& prepend(const _Elem* _String) noexcept;

	// Add at the begin
	XString& prepend(const _Elem* _String, size_type _Size) noexcept;

	// Add at the begin
	XString& prepend(const XString& _String) noexcept;

public:
	// Add at the end
	XString& append(_Elem _Char) noexcept;

	// Add at the end
	XString& append(const _Elem* _String) noexcept;

	// Add at the end
	XString& append(const _Elem* _String, size_type _Size) noexcept;

	// Add at the end
	XString& append(const XString& _String) noexcept;

public:
	// Inserts data from the specified location _Elem
	XString& insert(size_type _Pos, _Elem _Char) noexcept;

	// Inserts data from the specified location _Elem
	XString& insert(size_type _Pos, size_type _Count, _Elem _Char) noexcept;

	// Inserts data from the specified location const _Elem*
	XString& insert(size_type _Pos, const _Elem* _String) noexcept;

	// Inserts data from the specified location const _Elem*
	XString& insert(size_type _Pos, const _Elem* _String, size_type _Length) noexcept;

	// Inserts data from the specified location XString
	XString& insert(size_type _Pos, const XString& _String) noexcept;

public:
	// Removes the specified length of data from the specified location
	XString& remove(size_type _Pos, size_type _Length) noexcept;

	// Delete the same data as the parameter
	XString& remove(_Elem _Char) noexcept;

	// Delete the same data as the parameter
	XString& remove(_Elem _Char, Xanadu::CaseSensitivity _XCS) noexcept;

	// Delete the same data as the parameter
	XString& remove(const _Elem* _String) noexcept;

	// Delete the same data as the parameter
	XString& remove(const _Elem* _String, Xanadu::CaseSensitivity _XCS) noexcept;

	// Delete the same data as the parameter
	XString& remove(const _Elem* _String, size_type _Length) noexcept;

	// Delete the same data as the parameter
	XString& remove(const _Elem* _String, size_type _Length, Xanadu::CaseSensitivity _XCS) noexcept;

	// Delete the same data as the parameter
	XString& remove(const XString& _String) noexcept;

	// Delete the same data as the parameter
	XString& remove(const XString& _String, Xanadu::CaseSensitivity _XCS) noexcept;

public:
	// Replace the specified data
	XString& replace(size_type _Pos, size_type _Length, _Elem _After) noexcept;

	// Replace the specified data
	XString& replace(size_type _Pos, size_type _Length, const _Elem* _After) noexcept;

	// Replace the specified data
	XString& replace(size_type _Pos, size_type _Length, const _Elem* _After, size_type _LengthA) noexcept;

	// Replace the specified data
	XString& replace(size_type _Pos, size_type _Length, const XString& _After) noexcept;

public:
	// Replace the specified data
	XString& replace(_Elem _Before, _Elem _After) noexcept;

	// Replace the specified data
	XString& replace(_Elem _Before, _Elem _After, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(_Elem _Before, const _Elem* _After, size_type _LengthA) noexcept;

	// Replace the specified data
	XString& replace(_Elem _Before, const _Elem* _After, size_type _LengthA, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(_Elem _Before, const XString& _After) noexcept;

	// Replace the specified data
	XString& replace(_Elem _Before, const XString& _After, Xanadu::CaseSensitivity _XCS) noexcept;

public:
	// Replace the specified data
	XString& replace(const _Elem* _Before, _Elem _After) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, _Elem _After, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, const _Elem* _After, size_type _LengthA) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, const _Elem* _After, size_type _LengthA, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, const XString& _After) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, const XString& _After, Xanadu::CaseSensitivity _XCS) noexcept;

public:
	// Replace the specified data
	XString& replace(const _Elem* _Before, size_type _LengthB, _Elem _After) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, size_type _LengthB, _Elem _After, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, size_type _LengthB, const _Elem* _After, size_type _LengthA) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, size_type _LengthB, const _Elem* _After, size_type _LengthA, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, size_type _LengthB, const XString& _After) noexcept;

	// Replace the specified data
	XString& replace(const _Elem* _Before, size_type _LengthB, const XString& _After, Xanadu::CaseSensitivity _XCS) noexcept;

public:
	// Replace the specified data
	XString& replace(const XString& _Before, _Elem _After) noexcept;

	// Replace the specified data
	XString& replace(const XString& _Before, _Elem _After, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(const XString& _Before, const _Elem* _After, size_type _LengthA) noexcept;

	// Replace the specified data
	XString& replace(const XString& _Before, const _Elem* _After, size_type _LengthA, Xanadu::CaseSensitivity _XCS) noexcept;

	// Replace the specified data
	XString& replace(const XString& _Before, const XString& _After) noexcept;

	// Replace the specified data
	XString& replace(const XString& _Before, const XString& _After, Xanadu::CaseSensitivity _XCS) noexcept;

public:
	// Splits an array by the specified data
	std::list<XString> split(_Elem _Char) const noexcept;

	// Splits an array by the specified data
	std::list<XString> split(const _Elem* _Memory) const noexcept;

	// Splits an array by the specified data
	std::list<XString> split(const _Elem* _Memory, size_type _Size) const noexcept;

	// Splits an array by the specified data
	std::list<XString> split(const XString& _Bytes) const noexcept;

public:
	// Determine whether a character is a blank character, Same as iswspace.
	static bool isSpace(_Elem _Char) noexcept;

	// Format string (char* [%s]) (wchar_t* [%ls])
	static XString format(const char* _Format, ...) noexcept;

public:
	// [convert] convert to uppercase
	XString toUpper() const noexcept;

	// [convert] convert to lowercase
	XString toLower() const noexcept;

public:
	// [convert] convert to base64
	XString toBase64() const noexcept;

	// [convert] convert from base64
	static XString fromBase64(const _Elem* _String, size_type _Size) noexcept;

	// [convert] convert from base64
	static XString fromBase64(const XString& _Base64) noexcept;

public:
	// [convert] convert to Hex
	XString toHex() const noexcept;

	// [convert] convert from Hex
	static XString fromHex(const _Elem* _String, size_type _Size) noexcept;

	// [convert] convert from Hex
	static XString fromHex(const XString& _Hex) noexcept;

public:
	// [convert] convert to ASCII encoded string
	AString toAString() const noexcept;

	// [convert] convert from ASCII encoded string
	static XString fromAString(const char* _AString) noexcept;

	// [convert] convert from ASCII encoded string
	static XString fromAString(const AString& _AString) noexcept;

public:
	// [convert] convert to UNICODE encoded string
	WString toWString() const noexcept;

	// [convert] convert from UNICODE
	static XString fromWString(const wchar_t* _WString) noexcept;

	// [convert] convert from UNICODE
	static XString fromWString(const WString& _WString) noexcept;

public:
	// [convert] convert to UTF-8 encoded string
	UString toUString() const noexcept;

	// [convert] convert from UTF-8
	static XString fromUString(const char* _UString) noexcept;

	// [convert] convert from UTF-8
	static XString fromUString(const UString& _UString) noexcept;

public:
	// [convert] convert to native (Windows: ASCII / other: UTF-8) encoded string
	NString toNString() const noexcept;

	// [convert] convert from native (Windows: ASCII / other: UTF-8)
	static XString fromNString(const char* _NString) noexcept;

	// [convert] convert from native (Windows: ASCII / other: UTF-8)
	static XString fromNString(const NString& _NString) noexcept;

public:
	// [convert] convert to UTF-8 encoded byte array
	XByteArray toBytes() const noexcept;

	// [convert] convert from byte array
	static XString fromBytes(const XByteArray& _Bytes) noexcept;

public:
	// [convert] convert to UTF-8 encoded url
	XString toUrl() const noexcept;

	// [convert] convert from UTF-8 encoded url
	static XString fromUrl(const XString& _URL) noexcept;

public:
	// [convert] convert to char
	char toChar(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to unsigned char
	unsigned char toUChar(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to short
	short toShort(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to unsigned short
	unsigned short toUShort(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to int
	int toInt(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to unsigned int
	unsigned int toUInt(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to long
	long toLong(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to unsigned long
	unsigned long toULong(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to long long
	long long toLLong(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to unsigned long long
	unsigned long long toULLong(bool* _Ok = nullptr, int _Base = 10) const noexcept;

	// [convert] convert to float
	float toFloat(bool* _Ok = nullptr) const noexcept;

	// [convert] convert to double
	double toDouble(bool* _Ok = nullptr) const noexcept;

public:
	// [convert] convert from number
	XString& setNumber(char _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(unsigned char _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(short _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(unsigned short _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(int _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(unsigned int _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(unsigned long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(long long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(unsigned long long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	XString& setNumber(float _Value, char _Format, int _Prec) noexcept;

	// [convert] convert from number
	XString& setNumber(double _Value, char _Format, int _Prec) noexcept;

public:
	// [convert] convert from number
	static XString number(char _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(unsigned char _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(short _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(unsigned short _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(int _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(unsigned int _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(unsigned long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(long long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(unsigned long long _Value, int _Base = 10) noexcept;

	// [convert] convert from number
	static XString number(float _Value, char _Format = 'g', int _Prec = 6) noexcept;

	// [convert] convert from number
	static XString number(double _Value, char _Format = 'g', int _Prec = 6) noexcept;
};


// Standard enhancement function : stream <<
XANADU_CORE_EXPORT std::ostream& operator << (std::ostream& _OStream, const XString& _String) noexcept;

// Standard enhancement function : stream >>
XANADU_CORE_EXPORT std::istream& operator >> (std::istream& _IStream, XString& _String) noexcept;

// Standard enhancement function : getline
XANADU_CORE_EXPORT std::istream& getline(std::istream& _IStream, XString& _String, char _Delim) noexcept;

// Standard enhancement function : getline
XANADU_CORE_EXPORT std::istream& getline(std::istream& _IStream, XString& _String) noexcept;

#endif
